﻿using System.Collections.Generic;
using Script.Utils;
using Unity.Mathematics;
using UnityEngine;

namespace Script.Manager
{
    public class PoolManager : MonoBehaviour
    {
        public static PoolManager Instance;

        [SerializeField] private ActorTagPathDic actorTagPathDic;

        private Dictionary<ActorTag, ViewPool> viewPrefabPool = new Dictionary<ActorTag, ViewPool> ();

        private void Awake ()
        {
            if (Instance != null)
            {
                Destroy (Instance.gameObject);
            }

            Instance = this;
        }

        public View Spawn (ActorTag actorTag)
        {
            if (viewPrefabPool.TryGetValue (actorTag, out var pool) == false)
            {
                pool           = new ViewPool ();
                pool.prefab    = Resources.Load<GameObject> (actorTagPathDic[actorTag]);
                pool.SpawnRoot = new GameObject ($"_SpawnRoot_{actorTag.ToString ()}").transform;
                pool.PoolRoot  = new GameObject ($"_PoolRoot_{actorTag.ToString ()}").transform;

                pool.SpawnRoot.SetParent (transform);
                pool.SpawnRoot.localPosition = Vector3.zero;
                pool.SpawnRoot.localRotation = Quaternion.identity;
                pool.SpawnRoot.localScale    = Vector3.one;

                pool.PoolRoot.SetParent (transform);
                pool.PoolRoot.localPosition = Vector3.zero;
                pool.PoolRoot.localRotation = Quaternion.identity;
                pool.PoolRoot.localScale    = Vector3.one;

                viewPrefabPool.Add (actorTag, pool);
            }

            return pool.Spawn ();
        }

        public T Spawn<T> (ActorTag actorTag) where T : class, IView
        {
            return Spawn (actorTag) as T;
        }

        public bool Recycle (View view, ActorTag actorTag)
        {
            if (viewPrefabPool.TryGetValue (actorTag,out var pool)==false)
            {
                Destroy (view.gameObject);
                return false;
            }
            
            pool.DeSpawn (view);
            return true;
        }
    }
}